package com.yiji.fintech.musfinance.common.factory.strategy;

import com.google.common.collect.Maps;
import com.yiji.fintech.musfinance.common.annotation.NotifyAnnotation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.Set;

/**
 * 加载异步通知order与strategy关系
 * Created by ouwen@yiji.com} on 2017/9/25.
 */
@Component
@Slf4j
public class StrategyOrderLoadFactory implements ApplicationContextAware, InitializingBean {

    private String scanBasePath = "com.yiji.fintech.musfinance";
    private ApplicationContext applicationContext;
    private Map<Class,Class> strategyOrderMap = null;

    @Override
    public void afterPropertiesSet() throws Exception {
        strategyOrderMap = Maps.newConcurrentMap();
        scanStrategy();
    }
    /**
     * 扫描异步通知策略类
     */
    private void scanStrategy() {
        ClassPathScanningCandidateComponentProvider provider =
                new ClassPathScanningCandidateComponentProvider(false);
        provider.addIncludeFilter(new AnnotationTypeFilter(NotifyAnnotation.class));
        Set<BeanDefinition> components = provider.findCandidateComponents(scanBasePath);
        for (BeanDefinition component : components) {
            try {
                Class lister = Class.forName(component.getBeanClassName());
                NotifyAnnotation annotation = (NotifyAnnotation)lister.getAnnotation(NotifyAnnotation.class);
                strategyOrderMap.put(annotation.orderClass(),lister);
            } catch (ClassNotFoundException e) {
                log.error("扫描异步通知策略类反射异常【{}】",e.getMessage());
            }catch (Exception e){
                log.error("扫描异步通知策略类异常【{}】",e.getMessage());
            }
        }
    }
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
    public Map<Class, Class> getStrategyOrderMap() {
        return strategyOrderMap;
    }
}
